123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108(*
* Copyright (c) 2013-2017 Thomas Gazagnaire <thomas@gazagnaire.org>
* and Romain Calascibetta <romain.calascibetta@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)openLwt.InfixmoduleMake(S:Minimal.S)=structmoduleStore=SmoduleLog=structletsrc=Logs.Src.create"git.search"~doc:"logs git's internal search computation"include(valLogs.src_logsrc:Logs.LOG)endtypepred=[`CommitofStore.Hash.t|`Tagofstring*Store.Hash.t|`Treeofstring*Store.Hash.t|`Tree_rootofStore.Hash.t]letpredt?(full=true)h=lettagt=`Tag(Store.Value.Tag.tagt,Store.Value.Tag.objt)inLog.debug(funl->l~header:"predecessor""Read the object: %a."Store.Hash.pph);Store.readth>|=function|Errorerr->Log.err(funl->l~header:"predecessor""Retrieve an error when the search engine try to read %a: %a."Store.Hash.pphStore.pp_errorerr);[]|Ok(Store.Value.Blob_)->[]|Ok(Store.Value.Commitc)->(iffullthen[`Tree_root(Store.Value.Commit.treec)]else[])@List.map(funx->`Commitx)(Store.Value.Commit.parentsc)|Ok(Store.Value.Tagt)->iffullthen[tagt]else[]|Ok(Store.Value.Treet)->iffullthenList.map(fun{Store.Value.Tree.name;node;_}->`Tree(name,node))(Store.Value.Tree.to_listt)else[]typepath=[`Tagofstring*path|`Commitofpath|`Pathofstringlist]letfind_listfl=List.fold_left(funaccx->matchaccwithSome_->acc|None->fx)Nonellet_find_commit=find_list(function`Commitx->Somex|_->None)letfind_tree_root=find_list(function`Tree_rootx->Somex|_->None)letfind_tagl=find_list(function|`Tag(s,x)->ifl=sthenSomexelseNone|_->None)letfind_treel=find_list(function|`Tree(s,x)->ifs=lthenSomexelseNone|_->None)(* XXX: not tail-rec *)letrecfindthashpath=matchpathwith|`Path[]->Lwt.return(Somehash)|`Tag(l,p)->(predthash>>=funpreds->matchfind_taglpredswith|None->Lwt.return_none|Somes->findtsp)|`Commitp->(predthash>>=funpreds->matchfind_tree_rootpredswith|None->Lwt.return_none|Somes->findtsp)|`Path(h::p)->(predthash>>=funpreds->matchfind_treehpredswith|None->Lwt.return_none|Somes->findts(`Pathp))(* XXX: can do one less look-up *)letmemthpath=findthpath>>=functionNone->Lwt.returnfalse|Some_->Lwt.returntrueend