Re: [PATCH 1/3] cli: add insert --must-index option
authorTomi Ollila <tomi.ollila@iki.fi>
Wed, 23 Oct 2013 21:34:17 +0000 (00:34 +0300)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 17:57:34 +0000 (09:57 -0800)
2e/52704517ea94c84832c4f2acd89adac379a300 [new file with mode: 0644]

diff --git a/2e/52704517ea94c84832c4f2acd89adac379a300 b/2e/52704517ea94c84832c4f2acd89adac379a300
new file mode 100644 (file)
index 0000000..957c01d
--- /dev/null
@@ -0,0 +1,245 @@
+Return-Path: <tomi.ollila@iki.fi>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+       by olra.theworths.org (Postfix) with ESMTP id 50E84431FCF\r
+       for <notmuch@notmuchmail.org>; Wed, 23 Oct 2013 14:34:34 -0700 (PDT)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: 0\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none]\r
+       autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+       by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+       with ESMTP id 1Xefq4sItd1v for <notmuch@notmuchmail.org>;\r
+       Wed, 23 Oct 2013 14:34:28 -0700 (PDT)\r
+Received: from guru.guru-group.fi (guru.guru-group.fi [46.183.73.34])\r
+       by olra.theworths.org (Postfix) with ESMTP id B7D02431FB6\r
+       for <notmuch@notmuchmail.org>; Wed, 23 Oct 2013 14:34:27 -0700 (PDT)\r
+Received: from guru.guru-group.fi (localhost [IPv6:::1])\r
+       by guru.guru-group.fi (Postfix) with ESMTP id 533BC100217;\r
+       Thu, 24 Oct 2013 00:34:18 +0300 (EEST)\r
+From: Tomi Ollila <tomi.ollila@iki.fi>\r
+To: Austin Clements <amdragon@MIT.EDU>\r
+Subject: Re: [PATCH 1/3] cli: add insert --must-index option\r
+In-Reply-To: <20131023193209.GF20337@mit.edu>\r
+References: <1374365254-13227-1-git-send-email-novalazy@gmail.com>\r
+       <87ip048gbj.fsf@qmul.ac.uk>\r
+       <20130727151510.GA13750@hili.localdomain>\r
+       <87hadtxfrr.fsf@qmul.ac.uk>\r
+       <20130912001349.GA18821@hili.localdomain>\r
+       <87zjqhv264.fsf@zancas.localnet>\r
+       <m238o9fguj.fsf@guru.guru-group.fi> <87bo2xtdp2.fsf@unb.ca>\r
+       <m2eh7bu7t5.fsf@guru.guru-group.fi>\r
+       <20131023193209.GF20337@mit.edu>\r
+User-Agent: Notmuch/0.16+115~g11c2ff5 (http://notmuchmail.org) Emacs/24.3.1\r
+       (x86_64-unknown-linux-gnu)\r
+X-Face: HhBM'cA~<r"^Xv\KRN0P{vn'Y"Kd;zg_y3S[4)KSN~s?O\"QPoL\r
+       $[Xv_BD:i/F$WiEWax}R(MPS`^UaptOGD`*/=@\1lKoVa9tnrg0TW?"r7aRtgk[F\r
+       !)g;OY^,BjTbr)Np:%c_o'jj,Z\r
+Date: Thu, 24 Oct 2013 00:34:17 +0300\r
+Message-ID: <m2bo2fr7s6.fsf@guru.guru-group.fi>\r
+MIME-Version: 1.0\r
+Content-Type: text/plain; charset=utf-8\r
+Content-Transfer-Encoding: quoted-printable\r
+Cc: notmuch@notmuchmail.org\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+       <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Wed, 23 Oct 2013 21:34:34 -0000\r
+\r
+On Wed, Oct 23 2013, Austin Clements <amdragon@MIT.EDU> wrote:\r
+\r
+> Quoth Tomi Ollila on Oct 23 at 10:05 pm:\r
+>> On Thu, Oct 10 2013, David Bremner <david@tethera.net> wrote:\r
+>>=20\r
+>> > Tomi Ollila <tomi.ollila@iki.fi> writes:\r
+>> >>> I'm not opposed to doing an SONAME bump for 0.17. Are there other ABI\r
+>> >>> breaking changes that we have been holding back on? Can these maybe =\r
+go\r
+>> >>> through at the same time?\r
+>> >>\r
+>> >> Maybe something along these lines...\r
+>> >>\r
+>> >> (Quick draft for the API part; to start discussion before working too=\r
+ much\r
+>> >> for something that is going to be dropped...)\r
+>> >>\r
+>> >>  notmuch_status_t\r
+>> >> -notmuch_database_create (const char *path, notmuch_database_t **data=\r
+base);\r
+>> >> +notmuch_database_create (const char *path,\r
+>> >> +                         notmuch_loghook_t *loghook,\r
+>> >> +                         notmuch_database_t **database);\r
+>> >\r
+>> > Another idea floated (by Austin?) was to pass in an options struct, to\r
+>> > allow future options to be added without changing the function\r
+>> > signature. I guess with some care this could be done in an upwardly\r
+>> > compatible way.\r
+>>=20\r
+>> Maybe something like\r
+>>=20\r
+>> #define NOTMUCH_API_OPTIONS_VERSION 1\r
+>> typedef struct {\r
+>>         int options_version;\r
+>>         void (*log)(void *, int level, int status, const char * format, =\r
+...);\r
+>>         void * logdata;\r
+>> } notmuch_options_t;=20=20=20=20=20=20=20=20\r
+>>=20\r
+>> ...\r
+>>=20\r
+>> notmuch_status_t\r
+>> notmuch_database_create (const char *path,\r
+>>                      notmuch_options_t *options,\r
+>>                      notmuch_database_t **database);\r
+>> ...\r
+>>=20\r
+>> notmuch_status_t\r
+>> notmuch_database_open (const char *path,\r
+>>                        notmuch_database_mode_t mode,\r
+>>                        notmuch_options_t *options,\r
+>>                        notmuch_database_t **database);\r
+>>=20\r
+>> then in use:\r
+>>=20\r
+>> notmuch_options_t options =3D {\r
+>>        .options_version =3D NOTMUCH_API_OPTIONS_VERSION,\r
+>>=20\r
+>> .. =C3=A4sh, this has problem that the macro changes in header file\r
+>> but the structure initialization is not following automatically\r
+>> (in other fields than that). Therefore perhaps "fixing"\r
+>> the version macros:\r
+>>=20\r
+>> #define NOTMUCH_API_OPTIONS_VERSION_1 1\r
+>> /* #define NOTMUCH_API_OPTIONS_VERSION_2 2 // added in the future */\r
+>>=20\r
+>> notmuch_options_t options =3D {\r
+>>        .options_version =3D NOTMUCH_API_OPTIONS_VERSION_1,\r
+>>        .log =3D log_to_stderr,\r
+>>        .logdata =3D NULL\r
+>> };\r
+>>=20\r
+>> Well, this is one idea (does not sound as good as I initially\r
+>> thought...) how does other software tackle this kind of issues...\r
+>>=20\r
+>> If something like this is finally chosen we could provide easy\r
+>> transition path to allow NULL as options -- making notmuch CLI\r
+>> behave as it used to be (log to stderr...).\r
+>\r
+> Using a version number on the options makes it tricky to maintain\r
+> backwards compatibility, since you need code to read all past versions\r
+> of the structure.  A similar but, I think, better way would be to take\r
+> the size of the structure in the structure.  Something like:\r
+>\r
+> typedef struct {\r
+>     size_t options_length;\r
+>     ...\r
+> } notmuch_options_t;\r
+\r
+I thought this option too, but went to this version number scheme\r
+for more possibilities. We could discipline the backwards compatibility\r
+by always expecting old fields being the same and requiring structure\r
+to extend when version changes -- but could divert from that if absolutely\r
+necessary... But this would minimally require storing all the version\r
+structures and have version mapping there... But as this is more complex\r
+than your suggestion let's think it as the current solution of choice...\r
+\r
+> #define NOTMUCH_OPTIONS_INIT { sizeof(notmuch_options_t) }\r
+> // or without pre-processor, but requiring GCC attributes\r
+> static __attribute__((__unused__))\r
+> notmuch_options_t notmuch_options_init =3D { sizeof(notmuch_options_t) };\r
+>\r
+> NOTMUCH_OPTIONS_INIT/notmuch_options_init could also contain other\r
+> defaults, though it's best if the defaults are simply the zero\r
+> initializations of the various fields.\r
+\r
+Perhaps we should do=20\r
+#define NOTMUCH_OPTIONS_INIT { .options_length =3D sizeof (notmuch_options_=\r
+t) }\r
+\r
+IIRC this C99 initialization format makes rest of the structure initialize\r
+to zeros (I don't know/remember whether this is true in the one you\r
+suggested).\r
+\r
+Whenever new fields are added to the options structure they will always be\r
+zero in old code that doesn't know those fields -- therefore zero needs\r
+always be sensible default for every field. If we want to support setting\r
+new fields based on their existence then we need to add something like\r
+#define NOTMUCH_OPTIONS_VER 1 (or 20131024) so that code can #ifdef setting\r
+those and still support older notmuch versions...\r
+\r
+\r
+> Then, in code calling libnotmuch, you'd do something like\r
+>\r
+> notmuch_options_t options =3D NOTMUCH_OPTIONS_INIT;\r
+> options.log =3D log_to_stderr;\r
+> // ...\r
+>\r
+>\r
+> And in libnotmuch, we would do something like\r
+>\r
+> notmuch_status_t\r
+> notmuch_database_open (const char *path,\r
+>                        notmuch_database_mode_t mode,\r
+>                        const notmuch_options_t *options,\r
+>                        notmuch_database_t **database)\r
+\r
+Ah, the 'const'. I had the same in mind but forgot when doing it...\r
+\r
+> {\r
+>     notmuch_option_t real_options =3D NOTMUCH_OPTIONS_INIT;\r
+>     if (real_options.options_length < options.options_length)\r
+>         return error;\r
+>     memmove(&real_options, options, options.options_length);\r
+>     // ...\r
+> }\r
+>\r
+> This approach makes it free to add fields and we can always deprecate\r
+> fields as long as we leave the space in the structure.  This is based\r
+> roughly on how the Linux kernel deals with various structures that\r
+> have grown over time in the syscall ABI.\r
+\r
+Ack, good reference.\r
+\r
+> Another much more verbose but also more robust approach would be to\r
+> make notmuch_options_t opaque and provide setters (and getters, if\r
+> we're feeling benevolent).  I kind of like the simplicity of a struct.\r
+>\r
+> One thing to consider is what works best with bindings.  Presumably\r
+> the opaque structure wouldn't be a problem.  I've never had to wrap\r
+> anything like the struct approach, though, so I don't know if that's\r
+> easy or hard.\r
+\r
+Ruby & Go bindings use C wrapper(s), Python ctypes(*). Attaching working=20\r
+function pointer (& possibly data) can provide to be nontrivial challenge ;/\r
+We can provide some support code and/or structures in the library (in\r
+addtion/place of options as NULL...\r
+\r
+We'd like to hear comments from bindings' experts/developers.\r
+\r
+Tomi\r
+\r
+\r
+(*) A small attempt to show how c structures are available in python ctypes=\r
+:=20\r
+\r
+from ctypes import Structure, c_size_t\r
+\r
+class notmuch_options_t(Structure):\r
+    _fields__ =3D [ ('options_length', c_size_t), ... ]\r
+\r
+... adding function pointer to the Structure goes beyond my\r
+current skills (we cannot assume function pointer has the same size as\r
+(void) data pointer...)\r
+\r