Skip to content

Commit 9b95a1c

Browse files
author
Gregory Tsipenyuk
committed
access via UID, iterator for store,fetch,search
1 parent bfba0b7 commit 9b95a1c

14 files changed

+321
-114
lines changed

Makefile

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ STORAGE_SRC = storage/block.ml* storage/irminSrvIpc.ml* storage/irminStorage.ml*
44

55
IMAPLET_SRC = imaplet.ml account.ml* amailbox.ml* configuration.ml* connection.ml* contextlist.ml* contexts.ml* fetchregex.ml interpreter.ml* lex.mll parser.mly regex.ml* response.ml* server.ml* state.ml* states.ml utils.ml*
66

7-
all: imaplet irmin_store_srv build_irmin_store read_store
7+
all: imaplet srv store read_store
88

99
clean:
1010
ocamlbuild -clean
@@ -13,10 +13,10 @@ clean:
1313
imaplet:$(STORAGE_SRC) $(IMAPLET_SRC)
1414
corebuild -Is storage -cflag -annot -tag debug -verbose 6 -use-menhir -tag thread -use-ocamlfind -quiet -package extlib,str,async,email_message,async_unix,async_kernel,sexplib imaplet.native
1515

16-
irmin_store_srv: $(SRV_SRC)
16+
srv: $(SRV_SRC)
1717
corebuild -Is storage -use-ocamlfind -no-hygiene -tag thread -tag "syntax(camlp4o)" -package core,lwt,lwt.unix,lwt.syntax,irminsule.backend.git,sexplib.syntax,comparelib.syntax,bin_prot.syntax,email_message,extlib,str irminStorageSrv.native
1818

19-
build_irmin_store: $(STORAGE_SRC)
19+
store: $(STORAGE_SRC)
2020
corebuild -Is storage -pkgs async,email_message,async_unix,str,extlib build_irmin_store.native
2121

2222
read_store: read_store.ml storage/irminStorage.ml* storage/storageMeta.ml*

amailbox.ml

+55-17
Original file line numberDiff line numberDiff line change
@@ -435,8 +435,30 @@ let search mbx (keys:('a)States.searchKeys) (buid:bool) :
435435
let (module Mailbox) = storage_factory mbx name () in
436436
Mailbox.MailboxStorage.search_with Mailbox.this ~filter:(buid,keys) >>= fun acc -> return (`Ok acc)
437437

438+
let get_smallest_uid buid accs =
439+
if buid = false then
440+
return (Some 1)
441+
else
442+
let (module Accessor : StorageAccessor_inst) = accs in
443+
Accessor.StorageAccessor.reader_metadata Accessor.this (`Position 1) >>= function
444+
| `Eof -> return None
445+
| `Ok metadata -> return (Some metadata.uid)
446+
447+
let get_iterator mbx name accs buid sequence =
448+
let (module Mailbox) = storage_factory mbx name () in
449+
(if Iterator.SequenceIterator.single sequence then
450+
return Int.max_value
451+
else
452+
Mailbox.MailboxStorage.get_mailbox_metadata Mailbox.this >>= fun metadata ->
453+
if buid then return (metadata.uidnext-1) else return metadata.count
454+
) >>= fun max ->
455+
get_smallest_uid buid accs >>= function
456+
| None -> return None
457+
| Some min -> return (Some (Iterator.SequenceIterator.create sequence min max))
458+
438459
let fetch (mbx:t) (resp_writer:(string->unit)) (sequence:States.sequence) (fetchattr:States.fetch)
439460
(buid:bool) : [`NotExists|`NotSelectable|`Error of string|`Ok ] Deferred.t =
461+
let open Interpreter in
440462
match (selected_mbox mbx) with
441463
| None -> return (`Error "Not selected")
442464
| Some name ->
@@ -445,21 +467,31 @@ let fetch (mbx:t) (resp_writer:(string->unit)) (sequence:States.sequence) (fetch
445467
| `NotSelectable -> return (`NotSelectable)
446468
| `ValidMailbox ->
447469
let (module Mailbox) = storage_factory mbx name () in
448-
Mailbox.MailboxStorage.fold Mailbox.this ~exclusive:true ~init:() ~f:(fun () accs ->
449-
let rec doread accs seq =
450-
let (module Accessor : StorageAccessor_inst) = accs in
451-
let filter = Some (States.Key (States.Search_SeqSet sequence)) in
452-
Accessor.StorageAccessor.reader Accessor.this ?filter (`Position seq) >>= function
470+
Mailbox.MailboxStorage.fold Mailbox.this ~exclusive:true
471+
~init:()
472+
~f:(fun () accs ->
473+
(* should add the smallest uid to the the index header TBD
474+
*)
475+
get_iterator mbx name accs buid sequence >>= function
476+
| None -> return ()
477+
| Some it ->
478+
let (module Accessor : StorageAccessor_inst) = accs in
479+
let rec read = function
480+
| `End -> return ()
481+
| `Ok seq ->
482+
let pos = if buid then (`UID seq) else (`Position seq) in
483+
Accessor.StorageAccessor.reader Accessor.this pos >>= function
453484
| `Eof -> return ()
454-
| `NotFound -> doread accs (seq + 1)
485+
| `NotFound -> read (Iterator.SequenceIterator.next it)
455486
| `Ok (message,metadata) ->
456487
printf "============= %s" (Email_message.Mailbox.Message.to_string message);
488+
(* probably still need this since UID may not be sequential *)
457489
let res = Interpreter.exec_fetch seq sequence message metadata fetchattr buid in
458490
match res with
459-
| Some res -> resp_writer res; doread accs (seq + 1)
460-
| None -> doread accs (seq + 1)
491+
| Some res -> resp_writer res; read (Iterator.SequenceIterator.next it)
492+
| None -> read (Iterator.SequenceIterator.next it)
461493
in
462-
doread accs 1
494+
read (Iterator.SequenceIterator.next it)
463495
) >>= fun () -> return `Ok
464496

465497
let store (mbx:t) (resp_writer:(string->unit)) (sequence:States.sequence)
@@ -474,23 +506,29 @@ let store (mbx:t) (resp_writer:(string->unit)) (sequence:States.sequence)
474506
| `ValidMailbox ->
475507
let (module Mailbox) = storage_factory mbx name () in
476508
Mailbox.MailboxStorage.fold Mailbox.this ~exclusive:true ~init:() ~f:(fun () accs ->
477-
let rec doread accs seq =
478-
let (module Accessor : StorageAccessor_inst) = accs in
479-
Accessor.StorageAccessor.reader_metadata Accessor.this (`Position seq) >>= function
509+
let (module Accessor : StorageAccessor_inst) = accs in
510+
get_iterator mbx name accs buid sequence >>= function
511+
| None -> return ()
512+
| Some it ->
513+
let rec doread = function
514+
| `End -> return ()
515+
| `Ok seq ->
516+
let pos = if buid then (`UID seq) else (`Position seq) in
517+
Accessor.StorageAccessor.reader_metadata Accessor.this pos >>= function
480518
| `Eof -> return ()
519+
| `NotFound -> doread (Iterator.SequenceIterator.next it)
481520
| `Ok metadata ->
482521
let update metadata seq =
483-
Accessor.StorageAccessor.writer_metadata Accessor.this metadata
484-
(`Position seq) >>= function
522+
Accessor.StorageAccessor.writer_metadata Accessor.this metadata pos >>= function
485523
| `Eof -> return ()
486-
| `Ok -> doread accs (seq + 1)
524+
| `NotFound|`Ok -> doread (Iterator.SequenceIterator.next it)
487525
in
488526
match Interpreter.exec_store metadata seq sequence storeattr flagsval buid with
489-
| `None -> doread accs (seq + 1)
527+
| `None -> doread (Iterator.SequenceIterator.next it)
490528
| `Silent metadata -> update metadata seq
491529
| `Ok (metadata,res) -> resp_writer res;update metadata seq
492530
in
493-
doread accs 1
531+
doread (Iterator.SequenceIterator.next it)
494532
) >>= fun () -> return `Ok
495533

496534
(** if copy fails it should restore the mailbox, so need to copy TBD **)

irminStorageSrv.ml

+17-13
Original file line numberDiff line numberDiff line change
@@ -34,23 +34,25 @@ let create_socket () =
3434
socket
3535

3636
let get_pos = function
37-
| `Position pos -> pos
37+
| `Position p -> "seq " ^ (string_of_int p)
38+
| `UID u -> "uid " ^ (string_of_int u)
3839

3940
let handle_reader user loc filter pos =
40-
Printf.printf "------irminStorageSrv handle_reader %s %s %d\n%!" user loc (get_pos pos);
41+
Printf.printf "------irminStorageSrv handle_reader %s %s %s\n%!" user loc (get_pos pos);
4142
let mbox = IrminMailbox.create user loc in
42-
IrminMailbox.read_message mbox ?filter (get_pos pos) >>= function
43+
IrminMailbox.read_message mbox ?filter pos >>= function
4344
| `Ok (msg, meta) ->
4445
return (`Reader (`Ok (msg, meta)))
4546
| `NotFound -> return (`Reader `NotFound)
4647
| `Eof -> return (`Reader `Eof)
4748

48-
let handle_reader_metadata user loc pos =
49-
Printf.printf "------irminStorageSrv handle_reader_metadata %s %s %d\n%!" user loc (get_pos pos);
49+
let handle_reader_metadata user loc filter pos =
50+
Printf.printf "------irminStorageSrv handle_reader_metadata %s %s %s\n%!" user loc (get_pos pos);
5051
let mbox = IrminMailbox.create user loc in
51-
IrminMailbox.read_metadata mbox (get_pos pos) >>= function
52+
IrminMailbox.read_metadata mbox ?filter pos >>= function
5253
| `Ok meta -> return (`Reader_metadata (`Ok meta))
53-
| `NotFound -> return (`Reader_metadata `Eof)
54+
| `NotFound -> return (`Reader_metadata `NotFound)
55+
| `Eof -> return (`Reader_metadata `Eof)
5456

5557
let handle_writer user loc message metadata =
5658
Printf.printf "------irminStorageSrv handle_writer %s %s \n%!" user loc;
@@ -59,11 +61,12 @@ let handle_writer user loc message metadata =
5961
return (`Writer `Ok)
6062

6163
let handle_writer_metadata user loc pos metadata =
62-
Printf.printf "------irminStorageSrv handle_writer_metadata %s %s %d\n%!" user loc (get_pos pos);
64+
Printf.printf "------irminStorageSrv handle_writer_metadata %s %s %s\n%!" user loc (get_pos pos);
6365
let mbox = IrminMailbox.create user loc in
64-
IrminMailbox.update_metadata mbox (get_pos pos) metadata >>= function
66+
IrminMailbox.update_metadata mbox pos metadata >>= function
6567
| `Ok -> return (`Writer_metadata `Ok)
66-
| `NotFound -> return (`Writer_metadata `Eof)
68+
| `NotFound -> return (`Writer_metadata `NotFound)
69+
| `Eof -> return (`Writer_metadata `Eof)
6770

6871
let handle_exists user loc =
6972
Printf.printf "------irminStorageSrv handle_exists %s %s\n%!" user loc;
@@ -100,8 +103,9 @@ let handle_delete user loc =
100103
let handle_expunge user loc =
101104
Printf.printf "------irminStorageSrv handle_expunge %s %s\n%!" user loc;
102105
let mbox = IrminMailbox.create user loc in
103-
IrminMailbox.expunge mbox >>= fun () ->
104-
return `Expunge
106+
IrminMailbox.expunge mbox >>= fun res ->
107+
Printf.printf "%d records expunged\n%!" (Core.Std.List.length res);
108+
return (`Expunge res)
105109

106110
let handle_copy user loc1 loc2 filter =
107111
Printf.printf "------irminStorageSrv handle_copy %s %s %s\n%!" user loc1 loc2;
@@ -181,7 +185,7 @@ let process_request outchan msg =
181185
| `Mailbox_metadata (user, loc) -> handle_get_metadata user loc
182186
| `Move (user, loc1, loc2) -> handle_move user loc1 loc2
183187
| `Reader (user,loc,pos,filter) -> handle_reader user loc filter pos
184-
| `Reader_metadata (user,loc,pos) -> handle_reader_metadata user loc pos
188+
| `Reader_metadata (user,loc,filter,pos) -> handle_reader_metadata user loc filter pos
185189
| `Remove_account (user) -> handle_remove_account user
186190
| `Rebuild_index (user, loc) -> handle_rebuild_index user loc
187191
| `Search_with (user, loc, filter) -> handle_search_with user loc filter

iterator.ml

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
open Async.Std
2+
open States
3+
4+
module type SequenceIterator_intf =
5+
sig
6+
type t
7+
8+
(* sequence -> max in seq *)
9+
val create : sequence -> int -> int -> t
10+
11+
val single : sequence -> bool
12+
13+
val next : t -> [`Ok of int|`End]
14+
15+
end
16+
17+
module SequenceIterator : SequenceIterator_intf with type t = sequence*int
18+
ref*int ref*int ref*int*int =
19+
struct
20+
(* sequence, next element in sequence, current counter, max for the
21+
counter, overal min and max for the mailbox *)
22+
type t = sequence * int ref*int ref*int ref*int * int
23+
24+
let create seq min max = (seq,ref 0, ref 0, ref 0, min,max)
25+
26+
let single seq =
27+
if Core.Std.List.length seq = 1 then
28+
match (Core.Std.List.hd_exn seq) with
29+
| SeqNumber sn ->
30+
(
31+
match sn with
32+
| Number n -> true
33+
| Wild -> false
34+
)
35+
| SeqRange _ -> false
36+
else
37+
false
38+
39+
let next t =
40+
let s,nc,c,cmax,min,max = t in
41+
let get_n m = function
42+
| Number n -> n
43+
| Wild -> m
44+
in
45+
let update mi mx =
46+
c := mi;
47+
cmax := mx;
48+
`Ok !c
49+
in
50+
c := !c + 1;
51+
if !c > !cmax then (
52+
let seq = Core.Std.List.nth s !nc in
53+
match seq with
54+
| None -> `End
55+
| Some seq ->
56+
(
57+
nc := !nc + 1; (* ref to the next element in the sequence *)
58+
match seq with
59+
| SeqNumber sn ->
60+
(match sn with
61+
| Number n -> update n n
62+
| Wild -> update min max
63+
)
64+
| SeqRange (sn1,sn2) ->
65+
update (get_n min sn1) (get_n max sn2)
66+
)
67+
) else
68+
`Ok !c
69+
end

iterator.mli

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
open States
2+
3+
module type SequenceIterator_intf =
4+
sig
5+
type t
6+
7+
(* sequence -> max in seq *)
8+
val create : sequence -> int -> int -> t
9+
10+
val single : sequence -> bool
11+
12+
val next : t -> [`Ok of int|`End]
13+
14+
end
15+
16+
module SequenceIterator : SequenceIterator_intf with
17+
type t = sequence * int ref*int ref*int ref*int * int

read_store.ml

+2-1
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,13 @@ let rec selected user mbox =
5858
| "message" -> prompt "position? " >>= fun pos ->
5959
(
6060
let pos = int_of_string pos in
61-
IrminMailbox.read_message mbox pos >>= function
61+
IrminMailbox.read_message mbox (`Position pos) >>= function
6262
| `Ok (message,meta) ->
6363
Printf.printf "%s\n%!" (Sexp.to_string (sexp_of_mailbox_message_metadata meta));
6464
Printf.printf "%s\n%!" (Sexp.to_string (Mailbox.Message.sexp_of_t message));
6565
return ()
6666
| `NotFound -> Printf.printf "not found\n%!"; return ()
67+
| `Eof -> Printf.printf "eof\n%!"; return ()
6768
) >>= fun() -> selected user mbox
6869
| "list" ->
6970
IrminMailbox.list_store mbox >>= fun l ->

0 commit comments

Comments
 (0)