# Rowop reference

The Rowop class is defined in

    sched/Rowop.h

though usually there is no need to include it directly, just include

    sched/Unit.h

which will pull in the rest of the scheduling classes.

The Rowop in &Cpp; consists of all the same parts as in Perl API: a label, a row, and opcode.

It has one more item that's not really visible in the Perl API, the enqueueing mode, but it's semi-hidden in the &Cpp; API as well. The only place where it's used is in

    Unit::enqueueDelayedTray()

. This allows to build a tray of rowops, each with its own enqueueing mode, and then enqueue all of them appropriately in one go. This feature is kind of historic and will be removed somewhere soon.

The Rowop class inherits from Starget, usable in one thread only. Since it refers to the Labels, that are by definition single-threaded, this makes sense. A consequence is that you can't simply pass the Rowops between the threads. The passing-between-threads is handled by the Nexuses, performing the translation of the Labels along the way.

The opcodes are defined in the enum Rowop::Opcode, so you normally use them as

    Rowop::OP_INSERT

etc. The opcodes actually contain a bitmap of individual flags, defined in the enum Rowop::OpcodeFlags:

    Rowop::OCF_INSERT

and

    Rowop::OCF_DELETE

. You don't really need to use these flags directly unless you really, really want to.

Besides the 3 already described opcodes (OP_NOP, OP_INSERT and OP_DELETE) there is another one, OP_BAD. It's a special value returned by the string-to-opcode conversion method instead of the -1 returned by the other similar method. The reason is that OP_BAD is specially formatted to be understood by all the normal opcode type checks as NOP (i.e. both flags OCF_INSERT and OCF_DELETE are reset in it), while -1 would be seen as a combination of INSERT and DELETE. So if you miss checking the result of conversion on a bad string, at least you would get a NOP and not some mysterious operation. The reason why OP_BAD is not exported to Perl is that in Perl an

    undef

is used as the indication of the invalid value, and works even better.

There is a pretty wide variety of Rowop constructors:

    Rowop(const Label *label, Opcode op, const Row *row);
    Rowop(const Label *label, Opcode op, const Rowref &row);

    Rowop(const Label *label, Opcode op, const Row *row, int enqMode);
    Rowop(const Label *label, Opcode op, const Rowref &row, int enqMode);

    Rowop(const Rowop &orig);
    Rowop(const Label *label, const Rowop *orig);

The constructors with the explicit

    enqMode

are best not be used outside of the Triceps internals, and will eventually be obsoleted. The last two are the copy constructor, and the adoption constructor which underlies

    Label::adopt()

and can as well be used directly.

Once a rowop is constructed, its components can not be changed any more, only read.

    Opcode getOpcode() const;
    const Label *getLabel() const;
    const Row *getRow() const;
    int getEnqMode() const;

Read back the components of the Rowop. Again, the

    getEnqMode()

is on the way to obsolescence. And if you need to check the opcode for being an insert or delete, the better way is to use the explicit test methods, rather than getting the opcode and comparing it for equality:

    bool isInsert() const;
    bool isDelete() const;
    bool isNop() const;

Check whether the opcode requests an insert or delete (or neither).

The same checks are available as static methods that can be used on the opcode values:

    static bool isInsert(int op);
    static bool isDelete(int op);
    static bool isNop(int op);

And the final part is the conversion between the strings and integer values for the Opcode and OpcodeFlags enums:

    static const char *opcodeString(int code);
    static int stringOpcode(const char *op);
    static const char *ocfString(int flag, const char *def = "???");
    static int stringOcf(const char *flag);

As mentioned above,

    stringOpcode()

returns OP_BAD for the unknown strings, not -1.
Rowop
Opcode